package com.demo.activity;

import java.util.List;
import java.util.Vector;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

import android.media.AudioRecord;

public class RecordTool {

	private Vector<short[]> inBuf = new Vector<short[]>();
	private AtomicBoolean isRecording = new AtomicBoolean(false);
	private short[] sliceData = new short[0];
	private AtomicInteger sliceDataLength =  new AtomicInteger(1);

	static RecordTool recordTool = new RecordTool();
	Recordhanlder recordhanlder = null;

	private RecordTool(){}

	public boolean isRecording(){
		return isRecording.get();
	}

	public static RecordTool getInstance(){
		return recordTool;
	}

	public void setRecordhanlder(Recordhanlder recordhanlder) {
		this.recordhanlder = recordhanlder;
	}

	public Vector<short[]> getData(){
		return inBuf;
	}

	public short[] getSliceData(){
		return sliceData;
	}

	public void start(AudioRecord audioRecord, int recBufSize) {
		if(null != recordhanlder){
			recordhanlder.beforeStart();
		}
		if(isRecording.get()){
			return;
		}
		isRecording.set(true);
		clear();
		new RecordThread(audioRecord, recBufSize).start();
	}

	public void stop() {
		isRecording.set(false);
		if(null != recordhanlder){
			recordhanlder.AfterStoped(inBuf);
		}
	}

	public int getSliceDataLength() {
		return sliceDataLength.get();
	}

	private void clear(){
		inBuf.clear();
	}

	public static double getVolume(short[] buffer, int r) {
		long v = 0;
		for (int i = 0; i < buffer.length; i++) {
			v += buffer[i] * buffer[i];
		}
		double mean = v / (double) r;
		double volume = 10 * Math.log10(mean);
		return volume;
	}

	public static double getLevel(double avgEnergy){
		return Math.pow(10, 0.05 * (avgEnergy- 90)/2);
	}

	class RecordThread extends Thread {
		private int recBufSize;
		private AudioRecord audioRecord;

		public RecordThread(AudioRecord audioRecord, int recBufSize) {
			this.audioRecord = audioRecord;
			this.recBufSize = recBufSize;
		}

		public void run() {
			try {
				short[] buffer = new short[recBufSize];
				audioRecord.startRecording();
				while (isRecording.get()) {
					int bufferReadResult = audioRecord.read(buffer, 0, recBufSize);
					synchronized (inBuf) {
						inBuf.add(buffer);
						if(null != recordhanlder){
							recordhanlder.doInRecording(buffer.clone(), bufferReadResult);
						}
					}
				}
				audioRecord.stop();
			} catch (Throwable t) {
			}
		}

	};

	public static interface Recordhanlder {

		public void init();
		public void beforeStart();
		public void doInRecording(short[]  data, int bufferReadResult);
		public void AfterStoped(List<short[]>  data);

	}
}
